package main

import (
	"fmt"
	"github.com/pkg/errors"
	"time"
)

//v1 版本
//缺点: 参数不可配置(functional options) ; 代码不优雅

func V1main(){
	//创建一个 circuit
	c := NewCircuit(circuit{})
	fmt.Println(c)
	//调用 10 次成功
	for i := 0; i < 11; i++ {
		c.IncrementSuccess()
		//fmt.Println(res, err)
	}
	fmt.Println(c)
	//调用 10 次失败,触发熔断开关
	for i := 0; i < 11; i++ {
		c.IncrementFailed()
		//fmt.Println(res, err)
	}
	fmt.Println(c)
	//重置开关,不会成功
	c = c.Reset()
	fmt.Println(c)

	time.Sleep(time.Second * 60)
	//会成功
	c = c.Reset()
	fmt.Println(c)
}

type circuit struct {
	Success int
	Failed int
	status bool //暂时不存在half-open
	sleepTime int64
	statusTime time.Time
}

func NewCircuit(c circuit) *circuit{
	c.Success = 0
	c.Failed = 0
	c.status = false
	c.statusTime = time.Now()
	c.sleepTime = 60
	return &c
}
func (c *circuit) IncrementSuccess() (bool, error){
	if c.GetStatus() == false {
		c.Success++
		return true, errors.New("IncrementSuccess success")
	}
	return false, errors.New("IncrementSuccess failed")
}
func (c *circuit) IncrementFailed() (bool, error){
	//熔断器关闭状态
	if c.GetStatus() == false {
		c.Failed++
		//失败 10 次
		if c.Failed > 10 {
			//打开熔断器
			c.Open()
			return false, errors.New("IncrementFailed failed")
		} else {
			return true, errors.New("IncrementFailed success")
		}
	} else {
		return false, errors.New("IncrementFailed status is OPENED")
	}
}


type broker interface {
	GetStatus() bool
	Open()
	Close()
	Reset()
}

func (c *circuit) Reset() *circuit{
	//如果在时间窗口,不重置状态
	if c.statusTime.Unix() + c.sleepTime > time.Now().Unix(){
		return c
	}
	//超出时间窗口,重置状态
	return NewCircuit(circuit{})
}
func (c *circuit) GetStatus() bool{
	return c.status
}
func (c *circuit) Open(){
	c.status = true
}
func (c *circuit) Close(){
	c.status = false
}
